package com.wyp168.renrenfilm.core.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.wyp168.renrenfilm.core.dao.*;
import com.wyp168.renrenfilm.core.entity.*;
import com.wyp168.renrenfilm.core.vo.resp.FilmCountVO;
import com.wyp168.renrenfilm.core.vo.resp.FilmCountVO1;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.wyp168.renrenfilm.core.service.FilmService;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;


@Service("filmService")
public class FilmServiceImpl extends ServiceImpl<FilmDao, FilmEntity> implements FilmService {

    @Autowired
    WatchDao watchDao;

    @Resource
    HomeDao homeDao;

    @Autowired
    FilmLabelRelationDao filmLabelRelationDao;

    @Autowired
    FilmDao filmDao;



    @Override
    public PageInfo<FilmEntity> queryPage(Map<String, Object> params) {
        QueryWrapper<FilmEntity> queryWrapper = new QueryWrapper<>();
        String filmName = (String) params.get("key");
        if (!StringUtils.isEmpty(filmName)) {
            queryWrapper.like("film_name", filmName);
        }
        int page;
        int size;
        if (!Objects.isNull(params.get("page"))) {
            page = Integer.parseInt((String) params.get("page"));
        } else {
            page = 1;
        }

        if (!Objects.isNull(params.get("limit"))) {
            size = Integer.parseInt((String) params.get("limit"));
        } else {
            size = 100;
        }

        PageMethod.startPage(page, size);
        List<FilmEntity> filmEntities = baseMapper.selectList(queryWrapper);

        return new PageInfo<FilmEntity>(filmEntities);
    }

    @Override
    public List<FilmCountVO> countData() {

        //通过日期分组，获取到近七天的播放统计
        List<FilmCountVO> vos = watchDao.selectGroupDate();

        //补填数据，从今天往前推一周-1天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        calendar.add(Calendar.DAY_OF_MONTH, new Date().getDay() - 8);
        Date time = calendar.getTime();


        List<String> dates = vos.stream().map(FilmCountVO::getCountDate).collect(Collectors.toList());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for(int i = 0; i < 7; i ++) {
            String dateStr = sdf.format(time);
            if (!dates.contains(dateStr)) {
                vos.add(new FilmCountVO(0L, dateStr));
            }
            time = DateUtils.addDays(time, 1);
        }

        //给结果按照日期排序
        vos = vos.stream().sorted(Comparator.comparing(FilmCountVO::getCountDate)).collect(Collectors.toList());
        return vos;
    }

    @Override
    public List<FilmCountVO1> countData1() {
        List<FilmEntity> filmEntities = baseMapper.selectList(null);
        List<FilmCountVO1> counts = new ArrayList<>();
        filmEntities.forEach(entity -> {
            FilmCountVO1 filmCountVO1 = new FilmCountVO1();
            filmCountVO1.setFilmName(entity.getFilmName());
            filmCountVO1.setCount(entity.getPlayCount());
            counts.add(filmCountVO1);
        });
        return counts;
    }

    @Override
    public FilmEntity getByIdAndAddHotPoint(Long id) {
        FilmEntity filmEntity = baseMapper.selectById(id);

        //默认点击1次加10点热度
        filmEntity.setHotPoint(filmEntity.getHotPoint() + 10);
        baseMapper.updateById(filmEntity);
        return filmEntity;
    }

    @Override
    public Page<FilmEntity> recommonFilm(Map<String, Object> params) {
//        return null;
//        IPage page = (IPage) new Page<FilmEntity>((int) params.get("page"), (int) params.get("limit"));
        Integer page;
        if (null != params.get("page")) {
            page = Integer.parseInt(String.valueOf(params.get("page")));
        } else {
            page = 1;
        }
        Integer limit;
        if (null != params.get("limit")) {
            limit = Integer.parseInt(String.valueOf(params.get("limit")));
        } else {
            limit = 10;
        }
        Page<FilmEntity> filmEntityPage = filmDao.selectPage(new Page<FilmEntity>(page, limit), null);
        //当前分页的数据
        List<FilmEntity> records = filmEntityPage.getRecords();
        //封装推荐的资源id和权重映射
        Map<Long, Long> recommendMap = new HashMap<>();
        //根据username，获取标签id集合
        Map<Long, Long> labelIdCounts = getCurrentUserLabelId((String) params.get("username"));

        //遍历分页数据
        records.forEach(filmEntity -> {
            //获取资源和标签关系集合
            List<FilmLabelRelationEntity> filmLabel = filmLabelRelationDao.selectList(new QueryWrapper<FilmLabelRelationEntity>().lambda().eq(FilmLabelRelationEntity::getFilmId, filmEntity.getId()));
            //获取标签id集合
            List<Long> labelIds = filmLabel.stream().map(FilmLabelRelationEntity::getLabelId).distinct().collect(Collectors.toList());
            AtomicInteger score = new AtomicInteger();
            //判断当前标签是否存在于该用户观看过的标签中，如果存在，则权重+1，否则不动
            labelIds.forEach(labelId -> {
                if (labelIdCounts.keySet().contains(labelId)) {
                    score.getAndIncrement();
                }
            });
            //将资源id和权重映射到recommendMap中
            recommendMap.put(filmEntity.getId(), Integer.toUnsignedLong(score.get()));
        });

        //排序
        records.sort((f1, f2) -> {
            Long score1 = recommendMap.get(f1.getId());
            Long score2 = recommendMap.get(f2.getId());
            if (score1.equals(score2)) {
                //按照热度排序
                return f1.getHotPoint().compareTo(f2.getHotPoint());
            } else {
                //按照相关度排序
                return Long.compare(score1, score2);
            }
        });
        filmEntityPage.setRecords(records);
        return filmEntityPage;

    }

    /**
     * 获取当前用户观看过的电影的标签ids集合
     * 获取标签和播放次数的映射关系集合
     */
    public Map<Long, Long> getCurrentUserLabelId(String userName) {
        //根据username，获取所有play者ids
        List<Long> playIds = watchDao.selectList(new QueryWrapper<WatchEntity>().lambda().eq(StringUtils.isNotBlank(userName), WatchEntity::getWatcher, userName)).stream().map(WatchEntity::getPlayId).collect(Collectors.toList());
        //根据playIds，获取filmIds
        List<Long> filmIds = homeDao.selectList(new QueryWrapper<HomeEntity>().lambda().in(!CollectionUtils.isEmpty(playIds), HomeEntity::getId, playIds)).stream().map(HomeEntity::getFilmId).collect(Collectors.toList());
        //根据filmIds，获取labelIds
        List<Long> labelIds = filmLabelRelationDao.selectList(new QueryWrapper<FilmLabelRelationEntity>().lambda().in(!CollectionUtils.isEmpty(filmIds), FilmLabelRelationEntity::getFilmId, filmIds)).stream().map(FilmLabelRelationEntity::getLabelId).collect(Collectors.toList());
        //将labelIds分组统计，并返回Map集合
        return labelIds.stream().collect(Collectors.groupingBy(labelId -> labelId, Collectors.counting()));

    }



}